<template>
  <t-drawer v-model:visible="visible" :close-btn="true" size="30%" size-draggable>
    <t-chat layout="both" :clear-history="messageList.length > 0 && !streamLoading" @clear="handleClear">
      <t-chat-item
        v-for="(item, index) in messageList"
        :key="index"
        :name="item.name"
        :avatar="item.avatar"
        :datetime="item.datetime"
        :content="item.content"
        :role="item.role"
        :text-loading="index === 0 && textLoading"
      >
        <template #actions>
          <t-chat-action
            :content="item.content"
            :operation-btn="['replay', 'copy']"
            @operation="(value, context) => handleOperation(value, context, index)"
          />
        </template>
      </t-chat-item>
    </t-chat>
    <template #header>
      <t-avatar size="32px" shape="circle" image="https://tdesign.gtimg.com/site/chat-avatar.png"></t-avatar>
      <span
        style="margin-left: 16px; font-size: 20px; color: var(--td-font-gray-1); font-weight: 600; line-height: 28px"
        >Hi, &nbsp;我是AI</span
      >
    </template>
    <template #footer>
      <t-chat-input :stop-disabled="streamLoading" @send="handleSend" @stop="handleStop" />
    </template>
  </t-drawer>
</template>

<script setup lang="ts">
import {
  Chat as TChat,
  ChatAction as TChatAction,
  ChatInput as TChatInput,
  ChatItem as TChatItem,
  TdChatItemProps,
} from '@tdesign-vue-next/chat';
import { MessagePlugin } from 'tdesign-vue-next';
import { ref } from 'vue';

import { getMyConversation } from '@/api/ai/conversation';
import { deleteMessageListByConversationId, getMessageListByConversationId } from '@/api/ai/message';
import Record from '@/pages/order/details/components/Record.vue';
import stream from '@/utils/request/stream';

const props = defineProps({
  conversationId: {
    type: String,
    default: '1781604279872581778',
  },
});
const visible = ref(true);
const streamLoading = ref(false);
const textLoading = ref(false);
const abortController = ref();
const messageList = ref<TdChatItemProps[]>([]);
const handleAddMessage = ({ content, role }: { content: string; role: 'user' | 'assistant' }) => {
  messageList.value.unshift({
    avatar: {
      user: 'https://tdesign.gtimg.com/site/avatar.jpg',
      assistant: 'https://tdesign.gtimg.com/site/chat-avatar.png',
    }[role],
    content,
    role,
  });
};
const handleInit = async () => {
  messageList.value = [];
  try {
    const messageList = await getMessageListByConversationId({ conversationId: props.conversationId });
    if (messageList.length) {
      messageList.forEach((item: Record<string, any>) => {
        handleAddMessage({
          content: item.content,
          role: item.type,
        });
      });
    } else {
      const conversationInfo = await getMyConversation({ id: props.conversationId });
      handleAddMessage({
        content: conversationInfo.systemMessage,
        role: 'assistant',
      });
    }
  } catch ({ message }) {
    MessagePlugin.error(message);
  }
};
handleInit();
const handleStop = () => {
  if (abortController.value) abortController.value.abort();
  streamLoading.value = false;
  textLoading.value = false;
};
const handleSend = async (content: string) => {
  streamLoading.value = true;
  textLoading.value = true;
  handleAddMessage({ content, role: 'user' });
  handleAddMessage({ content: '', role: 'assistant' });
  abortController.value = new AbortController();
  await stream({
    body: {
      content,
      conversationId: props.conversationId,
      useContext: true,
    },
    signal: abortController.value.signal,
    onMessage: (message) => {
      textLoading.value = false;
      const { code, data } = JSON.parse(message.data);
      const lastMessage = messageList.value[0];
      if (code === 0) {
        lastMessage.content += data.receive.content;
      } else {
        lastMessage.role = 'error';
        lastMessage.content = data.msg;
      }
    },
    onError: (error) => {
      MessagePlugin.error(String(error));
      handleStop();
    },
    onClose: () => {
      handleStop();
    },
  });
};
const handleClear = () => {
  const params = {
    conversationId: props.conversationId,
  };
  deleteMessageListByConversationId(params)
    .then(() => {
      handleInit();
    })
    .catch(({ message }) => {
      MessagePlugin.error(message);
    });
};
const handleOperation = (operation: string, context: { e: MouseEvent }, index: number) => {
  if (operation === 'replay') {
    handleSend(messageList.value[index + 1].content);
  }
};
</script>
